#pragma once

#include <iostream>
#include <sys/epoll.h>
#include "Comm.hpp"

// 对事件的管理
class Epoller
{
private:
    std::string Event2String(uint32_t event)
    {
        std::string s;
        if (event & EPOLLIN)
        {
            s = "EPOLLIN";
        }
        if (event & EPOLLOUT)
        {
            s += " | EPOLLOUT";
        }
        if (event & EPOLLET)
        {
            s += " | EPOLLET";
        }
        return s;
    }

public:
    Epoller()
    {
        _epfd = epoll_create(128);
        if (_epfd < 0)
        {
            LOG(LogLevel::FATAL) << "epoll create fatal";
            exit(EPOLL_CREATE_ERROR);
        }
        LOG(LogLevel::DEBUG) << "create epoll fd success";
    }
    void AddEvent(int sockfd, uint32_t events)
    {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = sockfd;
        int n = epoll_ctl(_epfd, EPOLL_CTL_ADD, sockfd, &ev);
        if (n != 0)
        {
            LOG(LogLevel::INFO) << "Add " << sockfd << " events " << Event2String(events) << " to epoller failed";
            return;
        }
        LOG(LogLevel::INFO) << "Add " << sockfd << " events " << Event2String(events) << " to epoller success";
    }
    void DelEvent(int sockfd)
    {
        struct epoll_event ev;
        ev.data.fd = sockfd;
        int n = epoll_ctl(_epfd, EPOLL_CTL_DEL, sockfd, &ev);
        if (n != 0)
        {
            LOG(LogLevel::INFO) << "Del " << sockfd << " events " << " to epoller failed";
            return;
        }
        LOG(LogLevel::INFO) << "Del " << sockfd << " events " << " to epoller success";
    }
    void ModEvent(int sockfd, uint32_t events)
    {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = sockfd;
        int n = epoll_ctl(_epfd, EPOLL_CTL_MOD, sockfd, &ev);
        if (n != 0)
        {
            LOG(LogLevel::INFO) << "Mod " << sockfd << " events " << Event2String(events) << " to epoller failed";
            return;
        }
        LOG(LogLevel::INFO) << "Mod " << sockfd << " events " << Event2String(events) << " to epoller success";
    }
    int Wait(struct epoll_event revs[], int num, int timeout)
    {
        int n = epoll_wait(_epfd, revs, num, timeout);
        if (n < 0)
        {
            LOG(LogLevel::ERROR) << "epoll wait error";
            return -1;
        }

        return n;
    }
    ~Epoller()
    {
    }

private:
    int _epfd;
};

// class Poller
// {
// public:
//     virtual ~Poller()
//     {}
//     virtual void AddEvent() = 0;
//     virtual void DelEvent() = 0;
//     virtual void ModEvent() = 0;

// private:
// };

// class Selector : public Poller
// {

// };

// class Pollor : public Poller
// {

// };

// class Epoller : public Poller
// {

// };